package estimation.impl;

import model.vo.Logging;
import estimation.EstimationAbstract;

public class MinimosQuadradosJ3 extends EstimationAbstract {

	double aVariable;
	double bVariable;
	double lastDistance;
	double lastTime;
	double meanDistance;

	public void init() {
		aVariable = 0;
		bVariable = 0;
		lastDistance = 0;
		meanDistance = 0;
	}

	private void calculatePrediction() {

		init();

		double bVariableSquared = 0;
		meanDistance = meanDistance();

		Logging[] model = logger.toArray(new Logging[logger.size()]);
		
		if (model.length >= getWindowSize())
			for (int x = (model.length  - getWindowSize());x<model.length; x++) {

				double desviation = model[x].getDistance() - meanDistance;
				aVariable += model[x].getTime();
				bVariable += desviation * model[x].getTime();
				bVariableSquared += desviation * desviation;
				lastDistance = model[x].getDistance();
				lastTime = model[x].getTime();

			}

		aVariable = aVariable / getWindowSize();
		bVariable = bVariable / bVariableSquared;

	}

	private double meanDistance() {
		return getSumWindowBased() / availableRecords();// getSamples().size();
	}

	public double getPrediction(double position) {
		calculatePrediction();
		
		double firstCollectedTime = 0;
		for (Logging lm : super.getSamples()) {
			firstCollectedTime = lm.getTime();
		}
		
		double acumulatedDistance = (lastDistance+position) - meanDistance; // 0*lastDistance+meanDistance-position
		double calculated = aVariable + acumulatedDistance * bVariable;
		return getSeconds(calculated);
	}

	private double getSeconds(double milis) {
//		double firstCollectedTime = 0;
//		for (Logging lm : super.getSamples()) {
//			firstCollectedTime = lm.getTime();
//		}
		return ((milis-lastTime) / 1000);
	}

	protected double getSumWindowBased() {

		double sum = 0;

		Logging[] model = logger.toArray(new Logging[logger.size()]);

		if (model.length >= getWindowSize())
			for (int x = (model.length  - getWindowSize());x<model.length; x++) {
				sum += model[x].getDistance();
			}

		return sum;
	}
	
	private int availableRecords(){
		
		int counters=0;
		Logging[] model = logger.toArray(new Logging[logger.size()]);

		if (model.length >= getWindowSize())
			for (int x = (model.length  - getWindowSize());x<model.length; x++) {
				counters += 1;
			}
		
		return counters;
	}

	@Override
	public int getWindowSize() {
		return 3;
	}

}
